#pragma once

#include<iostream>
#include<queue>
#include<pthread.h>
#include"Log.hpp"
#include"Task.hpp"

#define NUM 6       //线程大小

class ThreadPool {
public:
    ThreadPool(int num = NUM):num_(num), stop_(false) {
        
        //初始化锁和条件变量
        pthread_mutex_init(&lock_, nullptr);
        pthread_cond_init(&cond_, nullptr);

    }
    ThreadPool(const ThreadPool& tp) = delete;
    ThreadPool operator=(const ThreadPool& tp) = delete;

    static ThreadPool* GetThreadPoolInstance() {

        static pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER;    //设置为静态
        if (single_instance_ == nullptr) {
            pthread_mutex_lock(&s_mutex);
            if (single_instance_ == nullptr) {
                single_instance_ = new ThreadPool();
                single_instance_->InitThreadPool();
            }
            pthread_mutex_unlock(&s_mutex);
        }
        return single_instance_;
    }

    bool InitThreadPool() {

        for (int i = 0; i < num_; ++i) {
            pthread_t tid;
            if (pthread_create(&tid, nullptr, ThreadRoutine, this) != 0) {
                LOG(FATAL, "Create ThreadPool failed!");
                return false;
            }
        }
        return true;
    }

    bool TaskQueueEmpty() {
        return task_queue_.size() == 0 ? true : false;
    }

    //处理任务
    static void* ThreadRoutine(void* args) {

        ThreadPool* tp = (ThreadPool*)args;
        pthread_detach(pthread_self());

        while (true) {
            Task t;
            tp->Lock();
            //防止因为误调用意外唤醒线程
            while (tp->TaskQueueEmpty()) {
                //没有任务，线程休眠
                tp->ThreadWait();
            }
            tp->Pop(t);
            tp->Unlock();
            t.Process();
        }
    }

    void Lock() {
        pthread_mutex_lock(&lock_);
    }
    void Unlock() {
        pthread_mutex_unlock(&lock_);
    }
    //线程休眠
    void ThreadWait() {
        pthread_cond_wait(&cond_, &lock_);
    }

    //线程唤醒
    void ThreadWake() {
        pthread_cond_signal(&cond_);
    }

    //添加任务
    void Push(const Task& task) {
        Lock();
        task_queue_.push(task);
        ThreadWake();
        Unlock();
    }

    //弹出任务
    void Pop(Task& task) {
        task = task_queue_.front();
        task_queue_.pop();
    }

    //判断是否出现错误
    bool Stop() {
        return stop_;
    }

    ~ThreadPool() {

        //释放锁和条件变量
        pthread_mutex_destroy(&lock_);
        pthread_cond_destroy(&cond_);
    }

private:
    int num_;
    bool stop_;
    std::queue<Task> task_queue_;
    pthread_mutex_t lock_;
    pthread_cond_t cond_;
    static ThreadPool* single_instance_;
};
ThreadPool* ThreadPool::single_instance_ = nullptr;